
public class LineEventProcessor extends DrawObjectEventProcessor
{
    private DrawObject TryCreateLine(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage Objects, DrawObject LineStart, DrawObject SingleSelectedObject)
    {
        if (UNDEFINED(SingleSelectedObject))
        {
            // when user just clicks on Grid, drawing Line is aborted

            LineStart = UNDEFINED;

            return LineStart;
        }

        DrawObject SelectedObject = SingleSelectedObject;

        // we check DrawObject types via "instanceof", special in this method,
        // because clearer like this here:

        if (SelectedObject instanceof TextField ||
            SelectedObject instanceof JavaCADUInputNode ||
            SelectedObject instanceof JavaCADULearningNode ||
            SelectedObject instanceof JavaCADUOutputNode ||
            SelectedObject instanceof Neuron ||
            SelectedObject instanceof NeuronInputNode ||
            SelectedObject instanceof NeuronOutputNode ||
            SelectedObject instanceof Node ||
            SelectedObject instanceof SampleAndHoldInputNode ||
            SelectedObject instanceof SampleAndHoldOutputNode ||
            SelectedObject instanceof VisualFieldPixel)
        {
            if (UNDEFINED(LineStart))
            {
                if (!(SelectedObject instanceof JavaCADU) &&
                    !(SelectedObject instanceof Neuron) &&
                    !(SelectedObject instanceof SampleAndHold))
                {
                    LineStart = SelectedObject;
                }
            }
            else if (LineStart == SelectedObject)
            {
                LineStart = UNDEFINED;
            }
            else if (false ||
                LineStart instanceof JavaCADU ||
                LineStart instanceof Line ||
                LineStart instanceof Neuron || // START must not be Neuron!
                LineStart instanceof NeuronInputField ||
                LineStart instanceof SampleAndHold ||
                LineStart instanceof VisualField)
            {
                LineStart = UNDEFINED;
            }
            else if (false ||
                ((LineStart instanceof NeuronInputNode && SelectedObject instanceof NeuronOutputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((LineStart instanceof NeuronInputNode && SelectedObject instanceof NeuronInputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((LineStart instanceof SampleAndHoldInputNode && SelectedObject instanceof SampleAndHoldOutputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((LineStart instanceof SampleAndHoldInputNode && SelectedObject instanceof SampleAndHoldInputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((LineStart instanceof VisualFieldPixel && SelectedObject instanceof VisualFieldPixel) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())))
            {
                LineStart = UNDEFINED;
            }
            else if (false ||
                ((SelectedObject instanceof NeuronInputNode && LineStart instanceof NeuronOutputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((SelectedObject instanceof NeuronInputNode && LineStart instanceof NeuronInputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((SelectedObject instanceof SampleAndHoldInputNode && LineStart instanceof SampleAndHoldOutputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((SelectedObject instanceof SampleAndHoldInputNode && LineStart instanceof SampleAndHoldInputNode) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())) ||
                ((SelectedObject instanceof VisualFieldPixel && LineStart instanceof VisualFieldPixel) && (LineStart.GetParentDrawObject() == SelectedObject.GetParentDrawObject())))
            {
                LineStart = UNDEFINED;
            }
            else if (Objects.ExistsLineFromTo(LineStart, SelectedObject)) // two lines in contrary directions allowed (flow donor loop or so)
            {
                LineStart = UNDEFINED;
            }
            else
            {
                Objects.AddObject("Line", LineStart, SelectedObject);

                LineStart = UNDEFINED;
            }
        }
        else
        {
            LineStart = UNDEFINED; // either a Line is created (see above), or attempt to create Line is aborted (else confusing)
        }

        return LineStart;
    }

    @Override
    public void TryProcessUserKeyboardAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
    {
        if (!(KeyboardEventsToBeProcessed(GUIElements)))
            return;

        return;
    }

    @Override
    public void TryProcessUserMouseAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
    {
        if (!(MouseEventsToBeProcessed(GUIElements)))
            return;

        // ****************************************************************
        if (MouseEventProcessor.IsMouseDragged() &&
            MouseEventProcessor.AnyButtonPressed())
        {
            if (DEFINED(LineStart))
            {
                LineStart = UNDEFINED;

                GUIElements.GetMainWindow().DoRedraw();
            }
        }
        // ****************************************************************
        if (MouseEventProcessor.IsLeftButtonClicked() &&
            NOT(KeyEventProcessor.AnyKeyPressed()) &&
            NOT(MultiSelectionExisting))
        {
            DrawObject LineStartOld = LineStart;

            LineStart = TryCreateLine(GUIElements, KeyEventProcessor, MouseEventProcessor, ObjectStorage, LineStart, SingleSelectedObject);

            if (LineStart != LineStartOld)
            {
                GUIElements.GetMainWindow().DoRedraw();
            }

            MoveMousePosLast = UNDEFINED_POINT; // no button pressed, no moving!
        }

        // ****************************************************************
        if (DEFINED(LineStart))
        {
            CursorManager.SetCrosshairCursorEnabled(true);
        }
        else
        {
            CursorManager.SetCrosshairCursorEnabled(false);
        }

        return;
    }
}
